package pt.iul.poo.file;

import java.awt.Dimension;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.Charset;
import java.util.LinkedList;

import pt.iul.poo.terrain.Earth;
import pt.iul.poo.terrain.Floor;
import pt.iul.poo.terrain.Sidewalk;

public class CharacterHandlerLevel {

	private Charset asciiCodification = Charset.defaultCharset();
	private int matrixCollumsSize;
	private int collumsCounted;
	private int linesCounted;
	private LinkedList<Floor> listElementsFromFile = new LinkedList<Floor>();
	private LinkedList<LinkedList<Floor>> matrix = new LinkedList<LinkedList<Floor>>();
	private Dimension imagesSize;
	private boolean startPositionDefined = false;

	public LinkedList<LinkedList<Floor>> readFromFile(String fileName,
			Dimension imagesSize) throws Exception {
		this.setImagesSize(imagesSize);
		try {
			InputStream in = new FileInputStream(fileName);
			Reader reader = new InputStreamReader(in, asciiCodification);
			Reader buffer = new BufferedReader(reader);
			handleCharacters(buffer);
			getMatrix().addLast(getListElementsFromFile());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return getMatrix();

	}

	private LinkedList<LinkedList<Floor>> getMatrix() {
		return matrix;
	}

	private void handleCharacters(Reader reader) throws IOException {
		int r;
		while ((r = reader.read()) != -1) {
			char ch = (char) r;
			putInList(ch);
			System.out.println("Do something with " + ch);
		}
	}

	private void putInList(char caracterChar) throws IllegalArgumentException,
			IOException {
		boolean validString = false;
		String caracterString = "" + caracterChar;
		Floor floorTemp = null;
		if (caracterString.equals("E")) {
			floorTemp = new Earth("terra.gif", getCollumsCounted()
					* getImagesSize().height, getLinesCounted()
					* getImagesSize().width, 0);
			validString = true;
			getListElementsFromFile().add(floorTemp);
		} else if (caracterString.equals("S")) {
			floorTemp = new Sidewalk("ceu.jpg",  getCollumsCounted()
					* getImagesSize().height, getLinesCounted()
					* getImagesSize().width, 0);
			validString = true;
			getListElementsFromFile().add(floorTemp);

		} else if (caracterString.equals("#")) {
			floorTemp = new Sidewalk("ceu.jpg",getCollumsCounted()
					* getImagesSize().height , getCollumsCounted()
					* getImagesSize().width, 0);
			if (!isStartPositionDefined()) {
				LinkedList<Floor> temporaryList = new LinkedList<>();
				temporaryList.add(floorTemp);
				getMatrix().addFirst(temporaryList);
				setStartPositionDefined(true);
				getListElementsFromFile().add(floorTemp);
			}
			validString = true;

		} else if (caracterString.equals("\n")) {
			if (getMatrixCollumsSize() == 0) {
				setMatrixCollumsSize(getCollumsCounted());
			}
			setLinesCounted(getLinesCounted() + 1);
			setCollumsCounted(0);
		}

		if (validString == true) {
			setCollumsCounted(getCollumsCounted() + 1);
		}
	}

	public int getMatrixCollumsSize() {
		return matrixCollumsSize;
	}

	public void setMatrixCollumsSize(int matrixCollumsSize) {
		this.matrixCollumsSize = matrixCollumsSize;
	}

	public int getCollumsCounted() {
		return collumsCounted;
	}

	public void setCollumsCounted(int collumsCounted) {
		this.collumsCounted = collumsCounted;
	}

	public int getLinesCounted() {
		return linesCounted;
	}

	public void setLinesCounted(int linesCounted) {
		this.linesCounted = linesCounted;
	}

	public LinkedList<Floor> getListElementsFromFile() {
		return listElementsFromFile;
	}

	public void setListElementsFromFile(LinkedList<Floor> listElementsFromFile) {
		this.listElementsFromFile = listElementsFromFile;
	}

	public Dimension getImagesSize() {
		return imagesSize;
	}

	public void setImagesSize(Dimension imagesSize) {
		this.imagesSize = imagesSize;
	}

	public boolean isStartPositionDefined() {
		return startPositionDefined;
	}

	public void setStartPositionDefined(boolean startPositionDefined) {
		this.startPositionDefined = startPositionDefined;
	}

	public void setMatrix(LinkedList<LinkedList<Floor>> matrix) {
		this.matrix = matrix;
	}
}